#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
use serde::Deserialize;
use std::collections::HashMap;
use wmi::{COMLibrary, Variant, WMIConnection};

#[derive(Deserialize, Debug)]
pub struct Win32_ComputerSystemProduct {
    // Caption: String,
    // Description: String,
    // IdentifyingNumber: String,
    // Name: String,
    // SKUNumber: Option<String>,
    // Vendor: String,
    // Version: String,
    UUID: Option<String>,
}

pub fn list() -> Result<(), Box<dyn std::error::Error>> {
    let results = query_struct()?;

    for os in results {
        println!("{:?}", os);
    }

    Ok(())
}

pub fn get(name: &str) -> Result<Option<String>, Box<dyn std::error::Error>> {
    match name {
        "uuid" => uuid(),
        _ => panic!("not support {}", &name),
    }
}

fn uuid() -> Result<Option<String>, Box<dyn std::error::Error>> {
    let results = query_struct()?;
    let r = results.first().expect("no uuid found");
    Ok(r.UUID.clone())
}

#[allow(dead_code)]
fn query() -> Result<Vec<HashMap<String, Variant>>, Box<dyn std::error::Error>> {
    let com_con = COMLibrary::new()?;
    let wmi_con = WMIConnection::new(com_con.into())?;

    let results: Vec<HashMap<String, Variant>> =
        wmi_con.raw_query("SELECT * FROM Win32_ComputerSystemProduct")?;

    Ok(results)
}

fn query_struct() -> Result<Vec<Win32_ComputerSystemProduct>, Box<dyn std::error::Error>> {
    let com_con = COMLibrary::new()?;
    let wmi_con = WMIConnection::new(com_con.into())?;

    let results: Vec<Win32_ComputerSystemProduct> =
        wmi_con.raw_query("SELECT * FROM Win32_ComputerSystemProduct")?;

    Ok(results)
}
